#include "include/cxxstd.h"
#include "include/lib.h"
#include "include/zero.h"
#include "corba.test.h"

using namespace zero;

namespace zerotest
{
TestResult* tr;
ORB* orb;

static MessageTypeInfo tiMessage;
static WorldException we;
static SessionException se;

ServerObject* callee;
CalleeLocation cl;

class ClientStub : public Object, virtual public HelloWorld
{

	public:
		virtual long hello(Message& a, char b) throw (SessionException, WorldException) {
			StaticRequest sr("hello");
			long result;
			StaticAny p1(&tiMessage, StaticAny::ARGUMENT_INOUT, &a),
					  p2(&tiChar, StaticAny::ARGUMENT_IN, &b),
					  res(&tiLong, StaticAny::RESULT, &result);
			sr.setResult(&res);
			sr << p1 << p2;
			orb->invokeAsyn(sr, *this, *callee, cl);
			switch (orb->maybeThrow(sr,
						1, static_cast<StaticTypeInfo*>(&se),
						2, static_cast<StaticTypeInfo*>(&we))) {
				case 1:
					throw SessionException(se);
				case 2:
					throw WorldException(we);
			}
			return result;
		}
} o;

class A : public Object, virtual public ELF
{
	public:
		virtual void run(ORB* orb) {
			zerotest::orb = orb;
			tr->clientCallTrace = 1;
			HelloWorld* hw = static_cast<HelloWorld*>(orb->query(typeid(HelloWorld).name(), &callee, &cl, (HelloWorld*) &o));

			Message inout; inout.c = 0x1; inout.s = 0x203; char in; in = 0x4;
			tr->clientOutput <<= sizeof(inout.c) * 8;
			tr->clientOutput += inout.c;
			tr->clientOutput <<= sizeof(inout.s) * 8;
			tr->clientOutput += inout.s;
			tr->clientOutput <<= sizeof(in) * 8;
			tr->clientOutput += in;
			int ret = hw->hello(inout, in);
			tr->clientInput <<= sizeof(ret) * 8;
			tr->clientInput += ret;
			tr->clientInput <<= sizeof(inout.c) * 8;
			tr->clientInput += inout.c;
			tr->clientInput <<= sizeof(inout.s) * 8;
			tr->clientInput += inout.s;

			try {
				hw->hello(inout, 0xe);
			} catch (SessionException& ex) {
				tr->clientExCatch <<= sizeof(int) * 8;
				tr->clientExCatch += 0xe2;
			} catch (WorldException& ex) {
				tr->clientExCatch <<= sizeof(int) * 8;
				tr->clientExCatch += ex.getCode();
			} catch (...) {
				tr->clientExCatch <<= sizeof(int) * 8;
				tr->clientExCatch += 0xe3;
			}
		}
} elf;

extern "C" ELF* pic_entry(TestResult* p)
{
	tr = p;
	return &elf;
}
}

// vim: foldmarker=<([{,}])> foldmethod=marker
